feat: add lock toggle to pin API config across all modes in workspace #11295
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Add a lock/unlock toggle inside the API config selector popover (next to the settings gear icon) that, when enabled, pins the currently selected API configuration across all mode switches in the current workspace.
When unlocked (default), switching modes loads each mode's saved API configuration (existing behavior). When locked, mode switches skip per-mode config loading entirely — the current API config stays active regardless of mode. Per-mode config mappings are not modified; they are simply bypassed at read time. Disabling the lock restores normal per-mode sticky behavior with all original mappings intact.
The setting is stored in
workspaceState(per-workspace), so locking in one workspace does not affect other workspaces.How It Works
The lock is implemented as a read-time override, not a write-time fan-out:
handleModeSwitch()checks the lock flag before loading per-mode config. If locked, it early-returns keeping the current API config active.createTaskWithHistoryItem()checks the lock flag before restoring mode-based API config from task history. If locked, the restoration is skipped.activateProviderProfile()has no lock-related logic — it writes to the current mode's config as normal, regardless of lock state.workspaceStateand posts state to the webview. No fan-out, no global side effects.This design ensures the workspace-scoped lock never mutates the global per-mode config mappings, preventing cross-workspace data destruction.
Changes
Core Implementation
packages/types/src/vscode-extension-host.ts— AddedlockApiConfigAcrossModestoExtensionStateandWebviewMessagetypessrc/core/webview/ClineProvider.ts— Reads lock state fromworkspaceState;handleModeSwitch()andcreateTaskWithHistoryItem()skip per-mode config loading when locked;getState()exposes lock flagsrc/core/webview/webviewMessageHandler.ts— Handler writes lock state toworkspaceStateand posts state to webviewwebview-ui/src/components/chat/ApiConfigSelector.tsx— Lock/unlock icon button in popover bottom bar next to settings gearwebview-ui/src/components/chat/ChatTextArea.tsx— Passes lock state + callback props to ApiConfigSelectorwebview-ui/src/context/ExtensionStateContext.tsx— DefaultlockApiConfigAcrossModes: falsei18n (18 locales)
chat.jsonlocale files updated with proper native translations for lock/unlock tooltip stringsTests
src/core/webview/__tests__/ClineProvider.lockApiConfig.spec.ts— Tests read-time override behavior (lock skips per-mode config, unlock preserves normal behavior)src/core/webview/__tests__/webviewMessageHandler.lockApiConfig.spec.ts— Tests handler sets flag without fan-outwebview-ui/src/components/chat/__tests__/ChatTextArea.lockApiConfig.spec.tsx— UI component testsworkspaceStatemock gaps in 4 existing test files